/**
 * Copyright (C) 2015-2018 IQIYI
 * All rights reserved.
 *
 * Author     : 王海斌
 * E-mail     : wanghaibin@qiyi.com
 * Version    :
 * Date       : Fri 07 Dec 2018 11:48:41 AM CST
 * Destription:
 *
 */
#include "stdafx.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "speedinfo.h"

SpeedInfo  gInfo;

int Connect(char * addr, char * port)
{
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int sfd=-1;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

    int ret = getaddrinfo(addr, port, &hints, &result);
    if (ret != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
        return sfd;
    }
    gInfo.FinishDNS();

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        sfd = socket(rp->ai_family, rp->ai_socktype,
                rp->ai_protocol);
        if (sfd == -1)
            continue;
        if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
            break;                  /* Success */
        close(sfd);
        sfd = -1;
    }
    gInfo.FinishConnect();

    if (rp == NULL) {               /* No address succeeded */
        fprintf(stderr, "Could not connect\n");
    }
    freeaddrinfo(result);           /* No longer needed */
    return sfd;
}

void ReadData(int fd, const char *file)
{
    acl::socket_stream sock;
    if(false == sock.open(fd)) {
        fprintf(stderr, "acl open failed.\n");
        return;
    }
    acl::http_request req(&sock, true);
    acl::http_header & hdr = req.request_header();
    hdr.set_url(file);
    if(false == req.write_head()) {
        printf("acl write_head failed.");
    } else {
        acl::http_client* cli = req.get_client();
        if(false == cli->read_head()) {
            printf("acl read_head failed.");
        } else {
            gInfo.FinishFirstByte();
            char buf[8192]={0};
            long long total = 0;
            int iRet = cli->read_body(buf, 8192);
            gInfo.FinishFirstData();
            while(iRet>0) {
                total += iRet;
                iRet = cli->read_body(buf, 8192);
            }
            gInfo.FinishData();
            if(iRet>0) {
                total += iRet;
            }
            gInfo.SetReadCount(total);
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc < 3) {
        fprintf(stderr, "Usage: %s host port file\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    gInfo.Start();
    int fd = Connect(argv[1], argv[2]);
    if(fd>0) {
        ReadData(fd, argv[3]);
        close(fd);
    }
    gInfo.End();
    return 0;
}

